#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <condition_variable>
#include <queue>
#include <functional>

std::mutex mtx;
std::condition_variable cv;
std::queue<std::function<void()>> queue;

// 生产者 消息队列queue
void producer()
{
    for (int i = 0; i < 10; i++)
    {
        {
            std::unique_lock<std::mutex> lck(mtx);
            queue.emplace([i]()
                        { std::cout << "Thread ID: " << std::this_thread::get_id() << " consumer " << i << std::endl; });
            std::cout << "producer " << i << std::endl;
        }
        // 通知消费者
        cv.notify_one();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    cv.notify_all();
}

// 消费者
void consumer()
{
    while (true)
    {
        std::unique_lock<std::mutex> lck(mtx);
        // 等待生产者通知或停止信号
        cv.wait(lck, []() { return !queue.empty(); });
        std::function<void()> task = queue.front();
        queue.pop();
        lck.unlock();
        try{
            task();
        }catch(std::exception &e){
            std::cout << "exception: " << e.what() << std::endl;
        }
    }
}

int main()
{
    std::thread t1(producer);
    std::thread t4(producer);
    std::thread t2(consumer);
    std::thread t3(consumer);

    t1.join();
    t2.join();
    t3.join();
    t4.join();

    return 0;
}